<?php
/**
 * jishupu-cms
 * @Author:技术铺<jishupu@qq.com>
 * @Date: 2022/3/16
 */

namespace App\Services;

use App\Filters\InfoFilter;
use App\Models\Info;
use App\Models\InfoCategory;

/**
 * 信息模块服务层
 *
 * Class InfoService
 * @package App\Services
 */
class InfoService
{
    /**
     * 获取链接
     * @param Info $info
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\UrlGenerator|mixed|string
     */
    static function getHref(Info $info)
    {
        $cateId = $info->infoCategory->id;
        $cateEnname = str_replace(' ', '', $info->infoCategory->enname);
        $name = $cateEnname ?: 'show';
        $url = url("/${name}/${cateId}.${info['id']}.html");
        return $info->href ?: $url;
    }

    /**
     * 设置链接相关属性
     * @param $item
     */
    static function setInfoLink(&$item = null)
    {
        if ($item != null) {
            $item['href'] = self::getHref($item);
            $item['href_'] = $item['href'] ? " href =${item['href']} " : '';
            $item['href_target_'] = $item->href_target ? " target =$item->href_target " : '';
            $item['rel_'] = $item->rel ? " rel =$item->rel " : '';
        }
    }

    /**
     * 获取图集模型的图片列表数据
     * @param Info $info
     * @return array|mixed
     */
    static function getImageList(Info $info)
    {
        $imageList = [];
        $model_id = $info->info_model_id;
        if ($model_id == 2) {
            $imageList = AttachmentService::getReponsePicture($info->infoPicture->image_list);
            collect($imageList)->each(function ($item, $index) use (&$imageList, $info) {
                $imageList[$index]['name'] = ''; // $info['title'];
            });
        }
        return $imageList;
    }

    /**
     * 获取面包屑
     * @param InfoCategory $cate
     * @return InfoCategory[]|array
     */
    static function getBreadcrumb(Info $info)
    {
        $href = self::getHref($info);
        $result = [
            [
                'title' => $info->title,
                'href_' => $href ? " href =${href} " : '',
                'href_target_' => $info->href_target ? " target =$info->href_target " : '',
                'rel_' => $info->rel ? " rel =$info->rel " : ''
            ]
        ];
        $cateBread = InfoCategoryService::getBreadcrumb($info->infoCategory);
        if ($cateBread) {
            $result = array_merge($cateBread, $result);
        }
        return $result;
    }

    /**
     * 根据条件获取信息列表
     * @param null $where // 查询条件： 数组或匿名函数
     * @param int $limit // 限制条数： 0代表不限制
     * @param string $order_by // 排序：原生写法，如：" top desc "
     * @return \Illuminate\Support\Collection
     */
    static function getList($where = null, $limit = 0, $order_by = "")
    {
        $query = Info::where('status', 1);
        if ($where != null) {
            $query = $query->where($where);
        }
        if ($limit > 0) {
            $query = $query->limit($limit);
        }
        if ($order_by != "") {
            $query = $query->orderByRaw($order_by);
        }
        $query = $query->orderBy('id', 'desc');
        $result = $query->get();

        // 封面图片处理
        $cover_image_ids = $query->pluck('cover_image');
        $getCoverImage = AttachmentService::previewList($cover_image_ids);
        $setCoverImage = [];
        collect($getCoverImage)->each(function ($item) use (&$setCoverImage, &$resetData) {
            $setCoverImage[$item['id']] = $item;
        });
        return collect($result)->each(function (&$item) use ($setCoverImage) {
            $item['image_url'] = AttachmentService::getDefaultImageUrl();
            if (!empty($item['cover_image'])) {
                $item['image_url'] = $setCoverImage[$item['cover_image']]['url'];
            }
            // link
            self::setInfoLink($item);
            // 图集模型：图片列表
            if ($item->info_model_id == 2) {
                $item['image_list'] = self::getImageList($item);
            }
        });
    }

    /**
     * 根据条件获取带分页信息列表
     * @param null $where // 查询条件： 数组或匿名函数
     * @param string $order_by // 排序：原生写法，如：" top desc "
     * @param int $pageSize // 每页大小
     * @param InfoFilter|null $infoFilter // 过滤
     * @return mixed
     */
    static function getPageList($where = null, $order_by = "", $pageSize = 20, InfoFilter $infoFilter = null)
    {
        $query = Info::where('status', 1);
        if ($where != null) {
            $query = $query->where($where);
        }
        if ($infoFilter != null) {
            $query = $query->filter($infoFilter);
        }
        if ($order_by != "") {
            $query = $query->orderByRaw($order_by);
        }
        $query = $query->orderBy('id', 'desc');
        $result = $query->paginate($pageSize);
        // 封面图片处理
        $cover_image_ids = $query->pluck('cover_image');
        $getCoverImage = AttachmentService::previewList($cover_image_ids);
        $setCoverImage = [];
        collect($getCoverImage)->each(function ($item) use (&$setCoverImage, &$resetData) {
            $setCoverImage[$item['id']] = $item;
        });
        collect($result->getCollection())->each(function (&$item) use ($setCoverImage) {
            $item['image_url'] = AttachmentService::getDefaultImageUrl();
            if (!empty($item['cover_image'])) {
                $item['image_url'] = $setCoverImage[$item['cover_image']]['url'];
            }
            // link
            self::setInfoLink($item);
            // 图集模型：图片列表
            if ($item->info_model_id == 2) {
                $item['image_list'] = self::getImageList($item);
            }
        });
        return $result;
    }

    /**
     * 上一篇
     * @param Info $info
     * @return mixed
     */
    static function getPrev(Info $info)
    {
        $result = Info::where([['id', '<', $info->id], ['info_category_id', $info->info_category_id]])->orderBy('id', 'desc')->first();
        self::setInfoLink($result);
        return $result;
    }

    /**
     * 下一篇
     * @param Info $info
     * @return mixed
     */
    static function getNext(Info $info)
    {
        $result = Info::where([['id', '>', $info->id], ['info_category_id', $info->info_category_id]])->orderBy('id', 'asc')->first();
        self::setInfoLink($result);
        return $result;
    }


    /**
     * 文章实时点击量
     * 场景：仅详情页
     */
    static function liveHits(Info $info)
    {
        $hits = $info->hits ?: 1;
        if (RedisService::hExists('info_hits', $info->id)) {
            $hits = RedisService::hGet('info_hits', $info->id);
        }
        return $hits;
    }

    /**
     * 新增文章访问量
     * @param Info $info
     */
    static function addHits(Info $info)
    {
        $lockKey = "info{$info->id}_hits_lock";
        $lock = RedisService::lock($lockKey);
        if ($lock->get()) {
            $hits = $info->hits;
            if (RedisService::hExists('info_hits', $info->id)) {
                $hits = RedisService::hGet('info_hits', $info->id);
            }
            $hits += 1;
            RedisService::hSet('info_hits', $info->id, $hits);
            $lock->release();
        }
    }

    /**
     * 更新文章访问量
     * 同步说明：采用任务调度，周期性更新
     */
    static function updateHits()
    {
        $allHits = RedisService::hGetAll('info_hits');
        if (!empty($allHits)) {
            $updateData = [];
            collect($allHits)->each(function ($hits, $infoId) use (&$updateData) {
                if ($hits > 0) {
                    $updateData[] = ['id' => $infoId, 'hits' => $hits];
                }
            });
            if (!empty($updateData)) {
                $info = new Info();
                $info->batchUpdate($updateData);
            }
        }
    }
}
